﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NLog;
using planerka.DataAccess.ViewModels;
using System.Web;
using planerka.DataAccess.Models;
using planerka.Common.Enums;
using System.Web.Security;
using planerka.Common;

namespace planerka.DataAccess.DataService
{
    public class UserService
    {
        private static Logger logger = LogManager.GetCurrentClassLogger();

        // получить список пользователей для пользователя с указанным guid
        public IEnumerable<user> getUserList(Guid userGuid)
        {
            List<long> userIDs = new List<long>();
            List<user> userList = new List<user>();
            _Repository<user> userRepo = new _Repository<user>();
            
            user _user = userRepo.FindAll(p => p.UserId == userGuid).FirstOrDefault();
            if (_user == null)
            {
                // некорректные данные
                return userList;
            }

            using (_Repository<userInvite> userInviteRepo = new _Repository<userInvite>())
                userIDs = userInviteRepo.FindAll(p => p.user_ID == _user.ID && p.invitedUser_ID != null).Select(p => (long)p.invitedUser_ID).ToList();

            userIDs.Add(_user.ID);

            return userRepo.FindAll(p => userIDs.Contains(p.ID)).OrderBy(p => p.nameView);
        }

        // загрузка модели
        public void fillUsersViewModel(ref usersViewModel uVM) 
        {
            IEnumerable<user> users;
            _Repository<user> userRepo = new _Repository<user>();
            
            users = getUserList(getCurrentUser().UserId); // userRepo.All();

            // фильтр - по признаку подтверждения почты
            switch (uVM.emailApproved_filter )
            {
                case emailApprovedFilter.all:
                    // взять все
                    break;
                case emailApprovedFilter.withApprovedEmail:
                    users = users.Where(p => p.isEmailApproved);
                    break;
                case emailApprovedFilter.withNotApprovedEmail:
                    users = users.Where(p => !p.isEmailApproved);
                    break;
            }

            uVM.users = users.ToList();
        }

        // чтение фильтра для списка пользователей
        public void load_usersVMfilter(ref usersViewModel uVM)
        {

            long currentUser_ID = getCurrentUser().ID;

            _Repository<userSetting> userSettingRepo = new _Repository<userSetting>();
            userSetting _userSetting = userSettingRepo.FindAll(p => p.user_ID == currentUser_ID).FirstOrDefault();
            if (_userSetting != null)
            {
                uVM.selectedUser_ID = _userSetting.users_selectedUser_ID != null ?
                (long)_userSetting.users_selectedUser_ID : 0;

                uVM.projectID_filter = _userSetting.users_projectID_filter != null ?
                    (long)_userSetting.users_projectID_filter : 0;

                try
                {
                    uVM.projectRoles_filter = _userSetting.users_projectRoles_filter != null ?
                        _userSetting.users_projectRoles_filter.Split(',').Select(p => Int32.Parse(p)).ToList() : null;
                }
                catch { }

                uVM.emailApproved_filter = (emailApprovedFilter)_userSetting.users_emailApproved_filter;

                uVM.FioEmailPhone_filter = _userSetting.users_FioEmailPhone_filter != null ?
                    _userSetting.users_FioEmailPhone_filter : "";    
            }
         
        }

        // создать пользователя при активации
        public void createUserWithApprovedEmail(MembershipUser user)
        {
            _Repository<user> userRepo = new _Repository<user>();
            user _user = new user();
            _user.email = user.Email;
            _user.surName = "";
            _user.isEmailApproved = true;
            _user.UserId = (Guid) user.ProviderUserKey;
            //_user.inviteGuid = Guid.NewGuid();

            userRepo.InsertInstance(_user);
            try {
                userRepo.Save();
            }
            catch (Exception ex) 
            {
                ExceptionUtility.LogException(logger, ex, 
                    "public void createUserWithApprovedEmail(MembershipUser user)", 
                    "ошибка добавления пользователя с подтвержденным email");
            }
        }

        // получить текущего пользователя
        public user getCurrentUser() 
        {
            Guid _Guid = (Guid)Membership.GetUser(HttpContext.Current.User.Identity.Name).ProviderUserKey;
            return new _Repository<user>().FindAll(p => p.UserId == _Guid).FirstOrDefault();
        }

        // получить текущего пользователя
        public user getUserByID(long ID)
        {
            return new _Repository<user>().FindAll(p => p.ID == ID).FirstOrDefault();
        }

        // добавить пользователя в круг
        public Guid? createInvite(long user_ID)
        {
            Guid? resGuid = null;
            using (_Repository<userInvite> userInviteRepo = new _Repository<userInvite>())
            {
                
                userInvite _userInvite = new userInvite();
                _userInvite.user_ID = user_ID;
                _userInvite.invitedUser_ID = 0;
                resGuid = Guid.NewGuid();
                _userInvite.inviteGuid = resGuid;

                userInviteRepo.InsertInstance(_userInvite);
                try
                {
                    userInviteRepo.Save();
                }
                catch (Exception ex)
                {

                    ExceptionUtility.LogException(logger, ex,
                "[HttpGet][Authorize]public ActionResult acceptInvite(string fromMail)",
                "ошибка сохранения статуса приглашения для user_ID:  " + user_ID);

                    resGuid = null;

                }
                
            }

            return resGuid;
        }

        // активировать инвайт
        public bool activateInvite(long invitedUserID, Guid inviteGuid)
        {
            bool success = true;
            using (_Repository<userInvite> userInviteRepo = new _Repository<userInvite>())
            {
                userInvite _userInvite = userInviteRepo
                        .FindAll(p => p.inviteGuid == inviteGuid)
                        .FirstOrDefault();

                if (_userInvite != null)
                {
                    
                    _userInvite.invitedUser_ID = invitedUserID;
                    _userInvite.inviteGuid = null;
                    
                    try
                    {
                        userInviteRepo.Save();
                    }
                    catch (Exception ex)
                    {

                        ExceptionUtility.LogException(logger, ex,
                            "[HttpGet][Authorize]public ActionResult acceptInvite(string fromMail)",
                            "ошибка сохранения статуса приглашения для user_ID:  " 
                            + _userInvite.user_ID + ", invitedUserID: " + invitedUserID 
                            + ", inviteGuid: " + inviteGuid);

                        success = false;

                    }
                }
            }

            return success;
            
        }

        // получить инвайт по Guid
        public userInvite getInviteByGuid(Guid inviteGuid)
        {
            userInvite _userInvite = null;
            using (_Repository<userInvite> userInviteRepo = new _Repository<userInvite>())
            {
                _userInvite = userInviteRepo
                        .FindAll(p => p.inviteGuid == inviteGuid)
                        .FirstOrDefault();
               
            }

            return _userInvite;

        }

        // получить список пользователей, 
        // которые указаны в моих проектах (администратора) как заказчики
        public IEnumerable<user> getMyCustomers(long currentUser_ID)
        {
            //IEnumerable<user> customers;
            IEnumerable<project> projectList = new ProjectService().getProjectsList(currentUser_ID);
            List<long> customersIDs = projectList.Where(p => p.customer_ID != null)
                .Select(p => (long) p.customer_ID).Distinct().ToList();

            return new _Repository<user>().FindAll(p => customersIDs.Contains(p.ID));
        }

        // инициализировать пользовательские настройки,
        // если нет - создать и записать
        public void initialyzeUserSettings()
        {
            long currentUser_ID = getCurrentUser().ID;

            _Repository<userSetting> userSettingRepo = new _Repository<userSetting>();
            userSetting _userSetting = userSettingRepo.FindAll(p => p.user_ID == currentUser_ID).FirstOrDefault();
            if (_userSetting == null)
            {
                _userSetting = new userSetting();
                _userSetting.user_ID = currentUser_ID;

                _userSetting.viewTableTasks_project = true;
                _userSetting.viewTableTasks_roles = true;
                _userSetting.viewTableTasks_status = true;
                _userSetting.viewTableTasks_priority = true;
                _userSetting.viewTableTasks_dates = true;
                _userSetting.viewTableTasks_sums = true;

                // insert
                userSettingRepo.InsertInstance(_userSetting);

                // save
                try { userSettingRepo.Save(); }
                catch (Exception ex)
                {
                    ExceptionUtility.LogException(logger, ex,
                        "public userSetting getUserSettings()",
                        "Ошибка сохранения userSetting для currentUser_ID: " + currentUser_ID);
                }
            }

            //return _userSetting;
        }
     
    }
}
